package com.baidu.mybuledemo;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    //设备UUID
    private String Uuid = "0000cc03-0000-1000-8000-00805f9b34fb";

    private List<BluetoothGattService> mBluetoothGattServices = null;
    private List<BluetoothGattCharacteristic> writeCharas = new ArrayList<BluetoothGattCharacteristic>();
    private List<BluetoothGattCharacteristic> readCharas = new ArrayList<BluetoothGattCharacteristic>();

    private LeDeviceListAdapter mLeDeviceListAdapter;
    private BluetoothManager mBluetoothManager;
    private BluetoothAdapter mBluetoothManagerAdapter;
    private BluetoothDevice bluetoothDevice;
    private BluetoothGatt mBluetoothGatt;
    private String deviceName;
    private String deviceAddress;
    private Button mFind;
    private Button mSend;
    private ListView mListView;
    //搜索蓝牙的回调方法,可以拿到设备deviced对象
    private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
//            找到蓝牙,将设备放入适配器
            mLeDeviceListAdapter.addDevice(device);
            mLeDeviceListAdapter.notifyDataSetChanged();
        }
    };

    private String TAG = this.getClass().getSimpleName();
    //链接Gatt的回调方法
    private android.bluetooth.BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            super.onConnectionStateChange(gatt, status, newState);
            if (gatt != mBluetoothGatt) {
                String logStr = String.format("%s != %s", gatt == null ? "null" : gatt.getDevice(), mBluetoothGatt == null ? "null" : mBluetoothGatt.getDevice());
                Log.e(TAG, logStr);
                return;
            }
            Log.e(TAG, "onConnectionStateChange： newState = " + newState);
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                startServicesDiscovery();
            }
        }

        public void startServicesDiscovery() {
            if (mBluetoothGatt != null) {
                mBluetoothGatt.discoverServices();
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            super.onServicesDiscovered(gatt, status);
            if (status == BluetoothGatt.GATT_SUCCESS) {
                getSupportedServices();
                processOldRWCharacteristic(mBluetoothGattServices);
            }
        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicRead(gatt, characteristic, status);
        }

        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
            super.onCharacteristicWrite(gatt, characteristic, status);
        }

    };
    private BluetoothGattCharacteristic gattCharacteristic;


    private void processOldRWCharacteristic(List<BluetoothGattService> mBluetoothGattServices) {
        writeCharas.clear();
        if (mBluetoothGattServices == null) {
            return;
        }
        for (BluetoothGattService gattService : mBluetoothGattServices) {
            // 判断当前服务的UUID是否和预定的服务的UUID相等
            if (gattService
                    .getUuid()
                    .toString()
                    .toUpperCase()
                    .equals(UUID.fromString(Uuid).toString().toUpperCase())) {
                List<BluetoothGattCharacteristic> gattCharacteristics = gattService
                        .getCharacteristics();
                // 获取到写的特征
                for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
                    final int charaProp = gattCharacteristic.getProperties();
                    Log.e(TAG, "charaProp = " + charaProp);
                    if (charaProp == 16) {
                        this.gattCharacteristic = gattCharacteristic;
                        setNotificationForCharacteristic(gattCharacteristic, true);
                        readCharas.add(gattCharacteristic);
                        Log.e(TAG, "发现的读特特征：" + gattCharacteristic.getUuid().toString());
                    } else {
                        if (!writeCharas.contains(gattCharacteristic)) {
                            writeCharas.add(gattCharacteristic);
                            Log.e(TAG, "发现的写特征：" + gattCharacteristic.getUuid().toString());
                        }
                    }
                }

            }
        }
    }

    private void setNotificationForCharacteristic(BluetoothGattCharacteristic gattCharacteristic, boolean enabled) {
        if (mBluetoothManagerAdapter == null || mBluetoothGatt == null) return;
        boolean success = mBluetoothGatt.setCharacteristicNotification(gattCharacteristic, enabled);
        if (!success) {
            Log.e("------", "Seting proper notification status for characteristic failed!");
        }
        BluetoothGattDescriptor descriptor = gattCharacteristic.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
        if (descriptor != null) {
            byte[] val = enabled ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE;
            descriptor.setValue(val);
            mBluetoothGatt.writeDescriptor(descriptor);
        }
    }

    public void getSupportedServices() {
        if (mBluetoothGattServices != null && mBluetoothGattServices.size() > 0)
            mBluetoothGattServices.clear();
        if (mBluetoothGatt != null) mBluetoothGattServices = mBluetoothGatt.getServices();

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化界面
        initView();
        //初始化蓝牙
        initBlueTooth();
    }

    private void initBlueTooth() {
        mBluetoothManager = (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothManagerAdapter = mBluetoothManager.getAdapter();
    }

    private void initView() {
        mFind = (Button) findViewById(R.id.find);
        mFind.setOnClickListener(this);
        mSend = (Button) findViewById(R.id.send);
        mSend.setOnClickListener(this);
        mListView = (ListView) findViewById(R.id.lv);
        //设置数据适配器
        mLeDeviceListAdapter = new LeDeviceListAdapter();
        mListView.setAdapter(mLeDeviceListAdapter);
        //设置点击
        mListView.setOnItemClickListener(listener);
    }

    AdapterView.OnItemClickListener listener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            bluetoothDevice = mLeDeviceListAdapter.getDevice(position);
            deviceName = bluetoothDevice.getName();
            deviceAddress = bluetoothDevice.getAddress();
            //点击链接该蓝牙
            connect();
        }


    };

    private void connect() {
        //点击链接 Gatt对象
        mBluetoothGatt = bluetoothDevice.connectGatt(this, false, mGattCallback);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.find:
//                找设备
                find();

                break;
            case R.id.send:
                send();
                break;
        }
    }

    //发送数据到蓝牙
    private void send() {
        byte[] bytes =  new byte[]{'a','b'};
        gattCharacteristic.setValue(bytes);
        mBluetoothGatt.writeCharacteristic(gattCharacteristic);
    }

    //搜索蓝牙,传入回调方法
    private void find() {
        mBluetoothManagerAdapter.startLeScan(leScanCallback);
    }

    private class LeDeviceListAdapter extends BaseAdapter {
        private ArrayList<BluetoothDevice> mLeDevices;
        private LayoutInflater mInflator;

        public LeDeviceListAdapter() {
            super();
            mLeDevices = new ArrayList<BluetoothDevice>();
            mInflator = MainActivity.this.getLayoutInflater();
        }

        public void addDevice(BluetoothDevice device) {
            if (!mLeDevices.contains(device)) {
                mLeDevices.add(device);
            }
        }

        public BluetoothDevice getDevice(int position) {
            return mLeDevices.get(position);
        }

        public void clear() {
            mLeDevices.clear();
        }

        @Override
        public int getCount() {
            return mLeDevices.size();
        }

        @Override
        public Object getItem(int i) {
            return mLeDevices.get(i);
        }

        @Override
        public long getItemId(int i) {
            return i;
        }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            ViewHolder viewHolder;
            // General ListView optimization code.
            if (view == null) {
                view = mInflator.inflate(R.layout.listitem_device, null);
                viewHolder = new ViewHolder();
                viewHolder.deviceAddress = (TextView) view.findViewById(R.id.device_address);
                viewHolder.deviceName = (TextView) view.findViewById(R.id.device_name);
                view.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) view.getTag();
            }

            BluetoothDevice device = mLeDevices.get(i);
            final String deviceName = device.getName();
            if (deviceName != null && deviceName.length() > 0)
                viewHolder.deviceName.setText(deviceName);
            else
                viewHolder.deviceName.setText(R.string.unknown_device);
            viewHolder.deviceAddress.setText(device.getAddress());

            return view;
        }
    }

    static class ViewHolder {
        TextView deviceName;
        TextView deviceAddress;
    }
}
